﻿using System;

namespace HW_0317_1
{
    public class Node<T>
    {
        public Node<T> Next { get; set; }
        public T Data { get; set; }
        public Node(T t)
        {
            Next = null;
            Data = t;
        }
    }
    public class GenericList<T>
    {
        private Node<T> head;
        private Node<T> tail;
        public GenericList()
        {
            tail = head = null;
        }
        public Node<T> Head
        {
            get => head;
        }
        public void Add(T t)
        {
            Node<T> n = new Node<T>(t);
            if (tail == null)
                head = tail = n; // head still points to a real element
            else
            {
                tail.Next = n;
                tail = n;
            }
        }
        public void ForEach(Action<T> action)
        {
            if (head == null) // be more cautious
                return;
            else
            {
                Node<T> p = head;
                while (p!=tail)
                {
                    action(p.Data); // Careful! It's "." !
                    p = p.Next;
                }
                action(p.Data); // do the tail
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("creating a int list ..."+"\n");
            GenericList<int> intlist = new GenericList<int>();
            Random r = new Random();
            for (int x = 0; x < 10; x++)
                intlist.Add(r.Next(0, 50));
            Console.Write("    Print the list using ForEach: ");
            /* for (Node<int> node = intlist.Head; node != null; node = node.Next)
                Console.WriteLine(node.Data); */
            intlist.ForEach (m => Console.Write(m+" "));
            Console.WriteLine();
            Console.Write("    Find the maximum of the list using ForEach: ");
            int max = -2147483648;
            // intlist.ForEach(m => { if (m >= max) max = m; else max = max; }); It's okay to use the next line's way. 
            intlist.ForEach(m => max = (m > max) ? m : max);
            Console.WriteLine(max);
            Console.Write("    Find the minimum of the list using ForEach: ");
            int min = 2147483647;
            intlist.ForEach(m => min = (m < min) ? m : min);
            Console.WriteLine(min);
            Console.Write("    Find the sum of the list using ForEach: ");
            int sum = 0;
            intlist.ForEach(m => sum += m);
            Console.WriteLine(sum);
            Console.WriteLine();
            Console.WriteLine("creating a string list ..." + "\n");
            GenericList<string> strlist = new GenericList<string>();
            for (int x = 0; x < 10; x++)
                strlist.Add("str" + x);
            for (Node<string> node = strlist.Head; node != null; node = node.Next)
                Console.WriteLine(node.Data);
        }
    }
}
